package emby.lang;

import emby.err.TypeError;

/**
 * The base class for all functions defined in java and not emby.
 * <br>
 * This class also provides some utility methods for argument number and type checking
 * as emby does not enforce anything by default.
 * @author Justin
 * @deprecated Use the call overload interface instead
 */
public abstract class NativeFunction extends EmbyFunction {

	private static final long serialVersionUID = 2541555139636582239L;

	public static boolean argsMatch( int line, Object[] args, Class<?>... types){
		if( types.length != args.length)return false;
		for(int i = 0; i< types.length; i++){
			if( !types[i].isAssignableFrom(args[i].getClass() )){
				//System.out.println("poop!"+args[i].getClass()+", "+types[i]);
				return false;
			}
		}
		return true;
	}

	public NativeFunction(String name, Integer _numargs){
		super(name, null, null, null);
		numargs = _numargs;
	}
	public NativeFunction(String name) {
		this(name, -1);
	}

	int numargs;

	public abstract Object execute(int line, Scope s, Object... args);

	/**
	 * Returns the number of arguments expected by this function.
	 * If this was not specified in the function definition or the function
	 * has optional parameters/ variable number of parameters,
	 * this returns -1.
	 * @return number of arguments or -1 if not applicable/ not specified.
	 */
	public int numArgs() {
		return numargs;
	}


	protected Object typeError(int line, Object[] args){
		StringBuilder errMessage = new StringBuilder();
		errMessage.append("function "+ name + " found arg types: ");
		for(int i = 0; i< args.length; i++){
			errMessage.append(args[i].getClass().toString());
			errMessage.append(", ");
		}
		throw new TypeError(line, errMessage.toString());
	}

	public String toString() {
		return "<native function \"" + name + "\">";
	}

}


